package com.strongbj.iot.devices.newlight.request.handle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.core.util.ContextUtils;
import com.strongbj.iot.devices.newlight.common.Executer;
import com.strongbj.iot.devices.newlight.common.NetMapping;
import com.strongbj.iot.devices.newlight.entity.ActiveTagCardData;
import com.strongbj.iot.devices.newlight.entity.ActiveTagData;
import com.strongbj.iot.devices.newlight.entity.ActiveTagReturnData;
import com.strongbj.iot.devices.newlight.entity.Reader;
import com.strongbj.iot.devices.newlight.entity.T;
import com.strongbj.iot.devices.newlight.entity.Tag;
import com.strongbj.iot.devices.newlight.message.NewLightMQMessage;
import com.strongbj.iot.devices.newlight.message.NewLightOSMessageFactory;
import com.strongbj.iot.devices.newlight.service.ReaderService;
import com.strongbj.iot.devices.newlight.service.TagService;
import com.strongbj.iot.mq.producer.TopicSender;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

/**
 * 标签点亮
 * 
 * @author lei_w
 *
 */
public class ActiveTagHandle implements IMessageHandle<NewLightMQMessage, Object> {

	private static Logger logger = LogManager.getLogger(ActiveTagHandle.class.getName());

	private TopicSender topicSender = (TopicSender) ContextUtils.getBean("topicSender");

	private TagService tagService = (TagService) ContextUtils.getBean("tagService");

	private ReaderService readerService = (ReaderService) ContextUtils.getBean("readerService");

	public static Map<String,List<String>> activeTagMap = new ConcurrentHashMap<>();
	
	/**
	 * 一个设备最大激活数量
	 */
	private static final int MAX_ACTIVE_COUNT = 6;
	
	private NewLightOSMessageFactory newLightOSMessageFactory = (NewLightOSMessageFactory) ContextUtils
			.getBean("newLightOSMessageFactory");

	private Map<String, List<ActiveTagReturnData>> resultMap = new ConcurrentHashMap<>();

	@Override
	public boolean isHandle(NewLightMQMessage msg) {
		if (msg.getActioncode().equals("activeTag")) {
			return true;
		} else {
			return false;
		}
	}

//	private void sendFailMessageToMQ(NewLightMQMessage srcData, String msg) {
//		NewLightMQMessage mes = new NewLightMQMessage();
//		mes.setActioncode("activeTagReturn");
//		mes.setGUID(srcData.getGUID());
//		ActiveTagReturnData atrd = new ActiveTagReturnData();
////		atrd.setErrCode("20002");
////		atrd.setResult("fail");
//		mes.setPostdata(atrd);
//	}

	@Override
	public Object handle(ChannelHandlerContext ctx, NewLightMQMessage msg) {
		logger.info("====收到标签点亮====");
		ActiveTagData datas = ((JSONObject) msg.getPostdata()).toJavaObject(ActiveTagData.class);
		List<ActiveTagReturnData> resultDatas = new ArrayList<>();
		resultMap.put(msg.getGUID(), resultDatas);
		Map<String, List<List<Tag>>> sendTagMap = new HashMap<>();
		// 统计标签所在读写器并保存到sendTagMap中。
		for (String at : datas.getTags()) {
			QueryWrapper<Tag> wrapper = new QueryWrapper<Tag>();
			wrapper.eq("ip_", at);
			Tag tag = tagService.getOne(wrapper);
			if (tag == null || tag.getShortAddress() == null || tag.getShortAddress() == "") {
				ActiveTagReturnData atr = new ActiveTagReturnData();
				atr.setTag(at);
				resultDatas.add(atr);
				atr.setSendActiveTagCommandSuccess(false);
				atr.setErrorMessage("未在系统库中找到此标签。");

				continue;
			}

			if (sendTagMap.containsKey(tag.getReader()) == false) {
				sendTagMap.put(tag.getReader(), new ArrayList<List<Tag>>());
				sendTagMap.get(tag.getReader()).add(new ArrayList<>());
			}
			if (sendTagMap.get(tag.getReader()).get(0).size() < MAX_ACTIVE_COUNT) {
				sendTagMap.get(tag.getReader()).get(0).add(tag);
			} else {
				List<Tag> tagList = new ArrayList<>();
				tagList.add(tag);
				sendTagMap.get(tag.getReader()).add(0, tagList);
			}
		}

		// 将标签分批次发送
		for (Map.Entry<String, List<List<Tag>>> tagGroup : sendTagMap.entrySet()) {
			QueryWrapper<Reader> query = new QueryWrapper<>();
			query.eq("code_", tagGroup.getKey());
			Reader reader = readerService.getOne(query);

			for (List<Tag> tags : tagGroup.getValue()) {
				if (reader == null || reader.getIp() == null || reader.getIp() == "") {
					for (Tag tag : tags) {
						ActiveTagReturnData atr = new ActiveTagReturnData();
						atr.setTag(tag.getIp());
						resultDatas.add(atr);
						atr.setSendActiveTagCommandSuccess(false);
						atr.setErrorMessage("未在系统库中找到此标签绑定的设备IP。");
					}
				} else if(NetMapping.getInstance().getChannel(reader.getIp())==null){
					for (Tag tag : tags) {
						ActiveTagReturnData atr = new ActiveTagReturnData();
						atr.setTag(tag.getIp());
						resultDatas.add(atr);
						atr.setSendActiveTagCommandSuccess(false);
						atr.setErrorMessage("Reader设备未连接。");
					}
				} else {
					List<String> shortAddr = new ArrayList<>();
					for (Tag tag : tags) {
						ActiveTagReturnData atr = new ActiveTagReturnData();
						atr.setTag(tag.getIp());
						resultDatas.add(atr);
						if(tag.getShortAddress()==null || tag.getShortAddress().equals("") || "0000".equals(tag.getShortAddress())) {
							atr.setSendActiveTagCommandSuccess(false);
							atr.setErrorMessage("标签未绑定设备");
						}else {
							atr.setSendActiveTagCommandSuccess(true);
							shortAddr.add(tag.getShortAddress());
						}
					}
					this.sendActiveTagGroupCommand(datas, reader, shortAddr);
				}
			}
		}

		this.sendReturnMessageToMQ(msg.getGUID(), resultDatas); // 发送反馈到MQ
		return null;
	}

	@Override
	public void destory() {
		// TODO Auto-generated method stub

	}

	private void sendReturnMessageToMQ(String guid, List<ActiveTagReturnData> resultDatas) {
		NewLightMQMessage mes = new NewLightMQMessage();
		mes.setActioncode("activeTagReturn");
		mes.setGUID(guid);
		mes.setPostdata(resultDatas);
		String json = JSON.toJSONString(mes);
		topicSender.send("wh.reader.command.response", json);
		logger.info("发送点亮反馈命令到MQ\r\n{}", json);
	}

	/**
	 * 向reader读写设备发送一组标签点亮命令
	 * 
	 * @param at
	 * @param reader
	 * @param shortTags
	 */
	private void sendActiveTagGroupCommand(ActiveTagData at, Reader reader, List<String> shortTags) {
		byte[] sendData = new byte[2 * Math.max(2, shortTags.size()) + 2];

		for (int i = 0; i < shortTags.size(); i++) {
			String tag = shortTags.get(i);
			byte[] pAddr = ByteUtil.hexStringToBytes(tag);
			if (i < 2) {
				System.arraycopy(pAddr, 0, sendData, i * 2, 2);
			} else {
				System.arraycopy(pAddr, 0, sendData, i * 2 + 2, 2);
			}
		}
		sendData[4] = clacLedState(at); // 设置灯状态
		sendData[5] = Integer.valueOf(shortTags.size()).byteValue(); // 设置灯数量

		byte[] timeStamp = T.getTimeStamp();
		byte[] req = newLightOSMessageFactory.createNewLightOSMessage(ByteUtil.addressToBytes(reader.getCode()),
				(byte) 0x06, sendData, timeStamp);
		ByteBuf bs = Unpooled.copiedBuffer(req);
		
		//使用队列发送点亮命令
		Map<String,Object> args = new HashMap<String,Object>();
		args.put("code", reader.getCode());
		args.put("shortTags", shortTags);
		args.put("req", req);
		Executer.RunCmd("ActiveTag", reader.getIp(), bs, args, timeStamp);
		
//		Channel channel = NetMapping.getInstance().getChannel(reader.getIp());
//
//		ChannelFuture cf = channel.writeAndFlush(bs);
//		cf.addListener(new ChannelFutureListener() {
//
//			@Override
//			public void operationComplete(ChannelFuture future) throws Exception {
//				if (future.isSuccess()) {
//					logger.info("发送点亮命令成功 设备编号:{} 标签编号:{} 命令={}  ", reader.getCode(),
//							JSON.toJSONString(shortTags, true), ByteUtil.byteArrToHexString(req, true));
//					
//					activeTagMap.put(ByteUtil.byteArrToHexString(timeStamp)+reader.getCode(),shortTags);
//				} else {
//					logger.debug("发送点亮命令失败 设备编号:{} 标签编号:{} 命令={}  ", reader.getCode(),
//							JSON.toJSONString(shortTags, true), ByteUtil.byteArrToHexString(req, true));
//				}
//			}
//
//		});
//		logger.info("发送点亮命令完成 命令={}", ByteUtil.byteArrToHexString(req));
	}

	/**
	 * 计算灯的状态
	 * 
	 * @param at
	 * @return
	 */
	private byte clacLedState(ActiveTagData at) {
		StringBuffer sb = new StringBuffer();
		sb.append("00"); // 保留位
		if (at.isLed4()) {
			sb.append("1");
		} else {
			sb.append("0");
		}
		if (at.isLed3()) {
			sb.append("1");
		} else {
			sb.append("0");
		}
		if (at.isLed2()) {
			sb.append("1");
		} else {
			sb.append("0");
		}
		if (at.isLed1()) {
			sb.append("1");
		} else {
			sb.append("0");
		}
		// 灯状态
		switch (at.getLedState()) {
		case ActiveTagCardData.FLASH_STATE: // 慢闪
			sb.append("01");
			break;
		case ActiveTagCardData.X_FLASH_STATE: // 快闪
			sb.append("10");
			break;
		case ActiveTagCardData.LIGHT_STATE: // 常亮
			sb.append("11");
			break;
		case ActiveTagCardData.OFF_STATE: // 关闭
		default:
			sb.append("00");
			break;
		}

		return ByteUtil.bitStringToByte(sb.toString());
	}
}
